/*
 * #%L
 * java model
 * %%
 * Copyright (C) 2009 - 2011 prefabware.com Stefan Isele
 * %%
 * All Rights Reserved.
 * This program is dual-licensed under the GNU General Public license
 * or a commercial license.
 * You may select to use one or the other of these licenses.
 * To obtain a commercial license please contact Stefan Isele at www.stefan-isele.de
 * Any modifications to this file must keep this entire header intact.
 * Redistribution, except as permitted by the selected license, is prohibited.
 * #L%
 */
package com.prefabware.jmodel.typefactory;

import java.lang.reflect.Method;

import com.prefabware.commons.QualifiedName;
import com.prefabware.jmodel.JType;
import com.prefabware.jmodel.JTypeDeclaration;
import com.prefabware.jmodel.annotation.JAnnotationClass;

/**
 * to create instances of JAnnotationClass for java annotations <br>
 * 
 * @author sisele_job
 * 
 */
public class JAnnotationClassTypeFactoryDelegee extends TypeFactoryDelegeeBase {

	protected JAnnotationClassTypeFactoryDelegee(TypeFactory typeFactory) {
		super();
	}

	private class JAnnotationClassVisitor extends JTypeClassVisitor {

		private JAnnotationClassVisitor(TypeFactory typeFactory, JType[] typeArguments) {
			super(typeFactory, typeArguments);
		}

		@Override
		public void visitMethod(Method method) {

			Object type = calcAnnotationMethodType(method.getReturnType());
			getJType().addAnnotationMethod(method.getName(), method.getDefaultValue(), type);
		}

		private Object calcAnnotationMethodType(Class<?> returnType) {
			// when reflecting an annotation, its obviously available at runtime
			// so all annotation methods will be created with the reflected  types
			// or 1-dimensional arrays thereof
			return returnType;
//			if (returnType.isPrimitive() || returnType.equals(String.class)) {
//			} else {
//				return getTypeFactory().getJType(returnType);
//			}
		}

		@Override
		public JAnnotationClass getJType() {
			return (JAnnotationClass) super.getJType();
		}

		@Override
		protected JType newJType(QualifiedName qualifiedName, JTypeDeclaration declaration, JType... typeArguments) {
			return  new JAnnotationClass(qualifiedName, declaration);
		}

	}

	@SuppressWarnings("unchecked")
	@Override
	public <TYPE extends JType> TYPE newJType(QualifiedName qualifiedName, JTypeDeclaration declaration,
			JType... typeArguments) {
		return (TYPE) new JAnnotationClass(qualifiedName, declaration);
	}

	@Override
	public boolean acceptType(Class<? extends JType> typeClass, QualifiedName qualifiedName) {
		return typeClass.equals(JAnnotationClass.class);
	}

	@Override
	public JAnnotationClassVisitor getVisitor(JType... typeArguments) {
		return new JAnnotationClassVisitor(typeFactory,typeArguments);
	}

}
